<route lang="jsonc" type="page">
{
"style": {
"navigationBarTitleText": "戳泡泡",
"navigationBarBackgroundColor": "#6c5ce7",
"navigationBarTextStyle": "white"
}
}
</route>

<script lang="ts" setup>
import { httpGet } from '@/http/http'

defineOptions({
  name: 'BubbleGame',
})

// 游戏设置
const gameSettings = ref({
  gameTime: 60, // 游戏时间（秒），0表示无限模式
  bubbleSpeed: 300, // 泡泡生成间隔（毫秒）
  maxBubbles: 8, // 屏幕最大泡泡数
  bubbleSize: { min: 100, max: 160 }, // 泡泡大小范围
  autoPopTime: 5, // 自动破碎时间（秒），0表示不自动破碎
})

// 戳泡泡游戏数据
const bubbleGame = ref({
  bubbles: [],
  score: 0,
  isPlaying: false,
  gameTimer: null,
  timeLeft: 60,
  isInfiniteMode: false,
})

// 设置对话框状态
const showSettingsModal = ref(false)

// 气泡ID计数器，确保每个气泡都有唯一ID
let bubbleIdCounter = 0

// 计算可见的气泡
const visibleBubbles = computed(() => {
  return bubbleGame.value.bubbles.filter(bubble => !bubble.hidden)
})

// 开始游戏
function startBubbleGame() {
  bubbleGame.value.isPlaying = true
  bubbleGame.value.score = 0
  bubbleGame.value.bubbles = []
  bubbleGame.value.timeLeft = gameSettings.value.gameTime
  bubbleGame.value.isInfiniteMode = gameSettings.value.gameTime === 0
  bubbleIdCounter = 0 // 重置ID计数器

  // 定期生成泡泡
  const bubbleTimer = setInterval(() => {
    // 只计算未隐藏的泡泡数量
    const visibleBubbles = bubbleGame.value.bubbles.filter(b => !b.hidden).length
    if (visibleBubbles < gameSettings.value.maxBubbles) {
      // 气泡形状：主要是不同的变形圆形
      const shapes = ['circle', 'oval', 'soft-circle', 'bubble']
      const selectedShape = shapes[Math.floor(Math.random() * shapes.length)]

      // 明亮的梦幻色系，没有暗色
      const colorPalettes = [
        { h: 200, s: 70, l: 85 }, // 天蓝色
        { h: 180, s: 65, l: 88 }, // 薄荷青
        { h: 280, s: 55, l: 90 }, // 薰衣草紫
        { h: 320, s: 65, l: 88 }, // 粉紫色
        { h: 45, s: 75, l: 90 }, // 香槟黄
        { h: 120, s: 50, l: 85 }, // 薄荷绿
        { h: 340, s: 70, l: 88 }, // 樱花粉
        { h: 30, s: 65, l: 90 }, // 蜜桃色
      ]
      const selectedColor = colorPalettes[Math.floor(Math.random() * colorPalettes.length)]

      // 破碎动画样式
      const burstStyles = ['burst1', 'burst2', 'burst3', 'burst4', 'burst5']
      const selectedBurstStyle = burstStyles[Math.floor(Math.random() * burstStyles.length)]

      const bubble = {
        id: ++bubbleIdCounter, // 使用递增计数器生成唯一ID
        x: Math.random() * 600,
        y: Math.random() * 1000,
        size: gameSettings.value.bubbleSize.min + Math.random() * (gameSettings.value.bubbleSize.max - gameSettings.value.bubbleSize.min),
        color: `hsl(${selectedColor.h}, ${selectedColor.s}%, ${selectedColor.l}%)`,
        shape: selectedShape,
        burstStyle: selectedBurstStyle, // 破碎样式
        popping: false,
        hidden: false, // 是否隐藏
        autoPopTimer: null, // 自动破碎定时器
      }
      bubbleGame.value.bubbles.push(bubble)

      // 设置自动破碎定时器
      if (gameSettings.value.autoPopTime > 0) {
        bubble.autoPopTimer = setTimeout(() => {
          autoPopBubble(bubble.id)
        }, gameSettings.value.autoPopTime * 1000)
      }
    }
  }, gameSettings.value.bubbleSpeed)

  // 分离倒计时计时器（每秒执行一次）
  let countdownTimer = null
  if (!bubbleGame.value.isInfiniteMode) {
    countdownTimer = setInterval(() => {
      bubbleGame.value.timeLeft--
      if (bubbleGame.value.timeLeft <= 0) {
        stopGame()
      }
    }, 1000) // 每1000毫秒（1秒）执行一次
  }

  // 将两个计时器保存起来
  bubbleGame.value.gameTimer = {
    bubbleTimer,
    countdownTimer,
  }
}

// 祝福语数据（从接口获取）
const blessings = ref([])
const audioConfigs = ref([])

// 加载祝福语配置
async function loadBlessings() {
  try {
    const response = await httpGet<any>('/api/miniapp/game/blessings/bubble_pop')
    
    if (response.code === 200 && response.data) {
      blessings.value = response.data.map(item => item.blessingText)
      console.log('祝福语加载成功:', blessings.value.length, '条')
    } else {
      console.warn('祝福语加载失败，使用默认数据')
      // 如果接口失败，使用默认祝福语
      blessings.value = ['你真棒', '加油', 'Great', 'Awesome', '继续努力']
    }
  } catch (error) {
    console.error('祝福语加载异常:', error)
    // 异常时使用默认祝福语
    blessings.value = ['你真棒', '加油', 'Great', 'Awesome', '继续努力']
  }
}

// 加载音效配置
async function loadAudioConfigs() {
  try {
    const response = await httpGet<any>('/api/miniapp/game/audios/bubble_pop')
    
    if (response.code === 200 && response.data) {
      audioConfigs.value = response.data
      console.log('音效配置加载成功:', audioConfigs.value.length, '条')
    } else {
      console.warn('音效配置加载失败，使用默认音效')
    }
  } catch (error) {
    console.error('音效配置加载异常:', error)
  }
}

// 祝福文字数组
const blessingsText = ref([])

// 祝福文字ID计数器
let blessingsIdCounter = 0

// 戳破泡泡
function popBubble(bubbleId: number) {
  const bubble = bubbleGame.value.bubbles.find(b => b.id === bubbleId)
  if (bubble && !bubble.popping && !bubble.hidden) {
    // 清除自动破碎定时器
    if (bubble.autoPopTimer) {
      clearTimeout(bubble.autoPopTimer)
      bubble.autoPopTimer = null
    }

    // 立即标记为正在破碎，防止重复点击同一个泡泡
    bubble.popping = true

    // 创建祝福文字
    createBlessingText(bubble)

    // 播放音效
    playPopSound()

    // 立即增加分数
    bubbleGame.value.score += 10

    // 延迟后隐藏泡泡（不从数组中删除）
    setTimeout(() => {
      bubble.hidden = true
      bubble.popping = false
    }, 500) // 增加延迟时间，确保动画播放完成
  }
}

// 自动破碎泡泡（超时）
function autoPopBubble(bubbleId: number) {
  const bubble = bubbleGame.value.bubbles.find(b => b.id === bubbleId)
  if (bubble && !bubble.popping && !bubble.hidden) {
    // 立即标记为正在破碎
    bubble.popping = true

    // 自动破碎不创建祝福文字，不增加分数，但播放音效
    playPopSound()
    // 只是让泡泡消失

    // 延迟后隐藏泡泡
    setTimeout(() => {
      bubble.hidden = true
      bubble.popping = false
    }, 500)
  }
}

// 创建祝福文字特效
function createBlessingText(bubble: any) {
  // 确保有祝福语数据
  if (!blessings.value || blessings.value.length === 0) {
    console.warn('暂无祝福语数据')
    return
  }
  
  // 随机选择一个祝福语
  const randomBlessing = blessings.value[Math.floor(Math.random() * blessings.value.length)]

  // 创建祝福文字对象
  const blessingText = {
    id: ++blessingsIdCounter,
    text: randomBlessing,
    x: bubble.x + bubble.size / 2, // 以气泡中心为起点
    y: bubble.y + bubble.size / 2,
    color: bubble.color,
    visible: true,
  }

  // 添加到祝福文字数组
  blessingsText.value.push(blessingText)

  // 1.5秒后移除文字
  setTimeout(() => {
    const index = blessingsText.value.findIndex(b => b.id === blessingText.id)
    if (index > -1) {
      blessingsText.value.splice(index, 1)
    }
  }, 1500)
}

// 播放爆泡音效
function playPopSound() {
  try {
    // 先尝试使用接口配置的音效
    const popAudioConfig = audioConfigs.value.find(config => config.audioType === 'pop')
    let audioUrl = 'https://example-luckcoder.oss-cn-beijing.aliyuncs.com/2025/09/09/a1b93e8c227842e9bd5f1428f12567b6.wav'
    let volume = 0.6
    
    if (popAudioConfig) {
      audioUrl = popAudioConfig.audioUrl || audioUrl
      volume = popAudioConfig.volume ? Number(popAudioConfig.volume) / 100 : volume
      console.log('使用配置音效:', audioUrl, '音量:', volume)
    }
    
    const audioContext = uni.createInnerAudioContext()
    audioContext.src = audioUrl
    audioContext.volume = volume

    audioContext.onError((err) => {
      console.log('网络音频播放失败，使用备用方案:', err)
      // 根据配置的fallbackType决定备用方案
      if (popAudioConfig && popAudioConfig.fallbackType === 'silent') {
        // 静默处理
        return
      } else if (popAudioConfig && popAudioConfig.fallbackType === 'toast') {
        // 提示处理
        uni.showToast({
          title: '破泡！',
          icon: 'none',
          duration: 200,
          mask: false,
        })
      } else {
        // 默认生成音效
        generatePopSound()
      }
    })

    audioContext.onCanplay(() => {
      audioContext.play()
    })

    audioContext.onEnded(() => {
      audioContext.destroy()
    })
  }
  catch (error) {
    console.log('音效播放失败:', error)
    generatePopSound()
  }
}

// 使用Web Audio API生成破泡音效
function generatePopSound() {
  try {
    // 在H5环境下使用Web Audio API
    // #ifdef H5
    const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()

    // 创建音频节点
    const oscillator = audioContext.createOscillator()
    const gainNode = audioContext.createGain()

    // 连接音频节点
    oscillator.connect(gainNode)
    gainNode.connect(audioContext.destination)

    // 设置音效参数（模拟破泡声）
    oscillator.frequency.setValueAtTime(800, audioContext.currentTime)
    oscillator.frequency.exponentialRampToValueAtTime(200, audioContext.currentTime + 0.1)

    gainNode.gain.setValueAtTime(0.3, audioContext.currentTime)
    gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.1)

    // 播放音效
    oscillator.start(audioContext.currentTime)
    oscillator.stop(audioContext.currentTime + 0.1)
    // #endif

    // 在非H5环境下使用系统提示音作为替代
    // #ifndef H5
    uni.showToast({
      title: '破泡！',
      icon: 'none',
      duration: 200,
      mask: false,
    })
    // #endif
  }
  catch (error) {
    console.log('生成音效失败:', error)
  }
}

// 停止游戏
function stopGame() {
  if (bubbleGame.value.gameTimer) {
    if (bubbleGame.value.gameTimer.bubbleTimer) {
      clearInterval(bubbleGame.value.gameTimer.bubbleTimer)
    }
    if (bubbleGame.value.gameTimer.countdownTimer) {
      clearInterval(bubbleGame.value.gameTimer.countdownTimer)
    }
    bubbleGame.value.gameTimer = null
  }

  // 清理所有气泡的自动破碎定时器
  bubbleGame.value.bubbles.forEach((bubble) => {
    if (bubble.autoPopTimer) {
      clearTimeout(bubble.autoPopTimer)
      bubble.autoPopTimer = null
    }
  })

  bubbleGame.value.isPlaying = false

  // 显示游戏结束提示
  uni.showModal({
    title: '游戏结束',
    content: `恭喜你得到 ${bubbleGame.value.score} 分！`,
    confirmText: '再来一局',
    cancelText: '返回',
    success: (res) => {
      if (res.confirm) {
        startBubbleGame()
      }
    },
  })
}

// 打开设置对话框
function openSettingsModal() {
  showSettingsModal.value = true
}

// 关闭设置对话框
function closeSettingsModal() {
  showSettingsModal.value = false
}

// 应用设置并重置游戏
function applySettingsAndReset() {
  if (bubbleGame.value.gameTimer) {
    if (bubbleGame.value.gameTimer.bubbleTimer) {
      clearInterval(bubbleGame.value.gameTimer.bubbleTimer)
    }
    if (bubbleGame.value.gameTimer.countdownTimer) {
      clearInterval(bubbleGame.value.gameTimer.countdownTimer)
    }
    bubbleGame.value.gameTimer = null
  }

  // 清理所有气泡的自动破碎定时器
  bubbleGame.value.bubbles.forEach((bubble) => {
    if (bubble.autoPopTimer) {
      clearTimeout(bubble.autoPopTimer)
      bubble.autoPopTimer = null
    }
  })

  bubbleGame.value.isPlaying = false
  bubbleGame.value.bubbles = []
  bubbleGame.value.score = 0
  bubbleGame.value.timeLeft = gameSettings.value.gameTime
  bubbleGame.value.isInfiniteMode = gameSettings.value.gameTime === 0
  bubbleIdCounter = 0 // 重置ID计数器
  blessingsText.value = [] // 清空祝福文字
  blessingsIdCounter = 0 // 重置祝福文字ID计数器
  closeSettingsModal()
}

// 重置游戏（显示设置对话框）
function resetGame() {
  openSettingsModal()
}

// 设置游戏时间
function setGameTime(time: number) {
  gameSettings.value.gameTime = time
}

// 设置泡泡生成速度
function setBubbleSpeed(speed: number) {
  gameSettings.value.bubbleSpeed = speed
}

// 设置最大泡泡数
function setMaxBubbles(count: number) {
  gameSettings.value.maxBubbles = count
}

// 设置自动破碎时间
function setAutoPopTime(time: number) {
  gameSettings.value.autoPopTime = time
}

// 获取速度显示文本
function getSpeedText(speed: number) {
  switch (speed) {
    case 600:
      return '慢'
    case 400:
      return '中等'
    case 300:
      return '快'
    case 200:
      return '极快'
    default:
      return '自定义'
  }
}

// 组件加载时初始化数据
onMounted(async () => {
  console.log('泡泡游戏页面加载，开始初始化数据...')
  await Promise.all([
    loadBlessings(),
    loadAudioConfigs()
  ])
  console.log('泡泡游戏数据初始化完成')
})

onUnmounted(() => {
  if (bubbleGame.value.gameTimer) {
    if (bubbleGame.value.gameTimer.bubbleTimer) {
      clearInterval(bubbleGame.value.gameTimer.bubbleTimer)
    }
    if (bubbleGame.value.gameTimer.countdownTimer) {
      clearInterval(bubbleGame.value.gameTimer.countdownTimer)
    }
  }

  // 清理所有气泡的自动破碎定时器
  bubbleGame.value.bubbles.forEach((bubble) => {
    if (bubble.autoPopTimer) {
      clearTimeout(bubble.autoPopTimer)
      bubble.autoPopTimer = null
    }
  })

  blessingsText.value = [] // 清空祝福文字
})
</script>

<template>
  <view class="bubble-game-container">
    <!-- 游戏信息栏 -->
    <view class="game-header">
      <view class="score-info">
        得分: {{ bubbleGame.score }}
      </view>
      <view class="time-info">
        <text v-if="!bubbleGame.isInfiniteMode">时间: {{ bubbleGame.timeLeft }}s</text>
        <text v-else>无限模式</text>
      </view>
    </view>

    <!-- 游戏区域 -->
    <view class="game-area">
      <!-- 未开始状态 -->
      <view v-if="!bubbleGame.isPlaying && bubbleGame.score === 0" class="game-start">
        <view class="start-icon">
          🫧
        </view>
        <view class="start-title">
          戳泡泡游戏
        </view>
        <view class="start-desc">
          点击屏幕上的泡泡来获得分数
        </view>
        <button class="start-btn" @click="startBubbleGame">
          开始游戏
        </button>
      </view>

      <!-- 游戏进行中 -->
      <view v-if="bubbleGame.isPlaying" class="bubble-container">
        <view
          v-for="bubble in visibleBubbles"
          :key="bubble.id"
          class="bubble"
          :class="{
            popping: bubble.popping,
            [bubble.burstStyle]: bubble.popping,
          }"
          :style="{
            left: `${bubble.x}rpx`,
            top: `${bubble.y}rpx`,
            width: `${bubble.size}rpx`,
            height: `${bubble.size}rpx`,
            backgroundColor: bubble.color,
          }"
          @touchstart.stop="popBubble(bubble.id)"
          @click.stop="popBubble(bubble.id)"
        />

        <!-- 祝福文字特效 -->
        <view
          v-for="blessing in blessingsText"
          :key="blessing.id"
          class="blessing-text"
          :style="{
            left: `${blessing.x}rpx`,
            top: `${blessing.y}rpx`,
            color: blessing.color,
          }"
        >
          {{ blessing.text }}
        </view>
      </view>
    </view>

    <!-- 游戏控制按钮 -->
    <view class="game-controls">
      <button
        v-if="!bubbleGame.isPlaying && bubbleGame.score > 0"
        class="control-btn restart-btn"
        @click="startBubbleGame"
      >
        重新开始
      </button>
      <button
        v-if="bubbleGame.isPlaying"
        class="control-btn stop-btn"
        @click="stopGame"
      >
        结束游戏
      </button>
      <button
        class="control-btn reset-btn"
        @click="resetGame"
      >
        重置游戏
      </button>
    </view>

    <!-- 游戏说明 -->
    <view class="game-instructions">
      <view class="instruction-title">
        游戏规则
      </view>
      <view class="instruction-list">
        <view class="instruction-item">
          • 点击屏幕上的泡泡来获得分数
        </view>
        <view class="instruction-item">
          • 每个泡泡价值10分
        </view>
        <view class="instruction-item">
          • {{
            bubbleGame.isInfiniteMode ? '无限模式，尽情享受戳泡泡的乐趣' : `游戏时间${gameSettings.gameTime}秒，争取更高分数`
          }}
        </view>
        <view class="instruction-item">
          • 泡泡会不断出现，手速要快哦
        </view>
        <view class="instruction-item">
          • {{
            gameSettings.autoPopTime > 0 ? `泡泡会在${gameSettings.autoPopTime}秒后自动消失` : '泡泡不会自动消失，尽快点击获得分数'
          }}
        </view>
      </view>
    </view>

    <!-- 设置对话框 -->
    <view v-if="showSettingsModal" class="settings-modal" @click="closeSettingsModal">
      <view class="settings-content" @click.stop>
        <view class="settings-header">
          <view class="settings-title">
            游戏设置
          </view>
          <view class="close-btn" @click="closeSettingsModal">
            ×
          </view>
        </view>

        <view class="settings-body">
          <!-- 游戏时间设置 -->
          <view class="setting-group">
            <view class="setting-label">
              游戏时间
            </view>
            <view class="setting-options">
              <view
                v-for="time in [30, 60, 90, 120, 0]"
                :key="time"
                class="setting-option"
                :class="{ active: gameSettings.gameTime === time }"
                @click="setGameTime(time)"
              >
                {{ time === 0 ? '无限' : `${time}s` }}
              </view>
            </view>
          </view>

          <!-- 泡泡生成速度 -->
          <view class="setting-group">
            <view class="setting-label">
              生成速度
            </view>
            <view class="setting-options">
              <view
                v-for="speed in [600, 400, 300, 200]"
                :key="speed"
                class="setting-option"
                :class="{ active: gameSettings.bubbleSpeed === speed }"
                @click="setBubbleSpeed(speed)"
              >
                {{ getSpeedText(speed) }}
              </view>
            </view>
          </view>

          <!-- 最大泡泡数 -->
          <view class="setting-group">
            <view class="setting-label">
              屏幕泡泡数
            </view>
            <view class="setting-options">
              <view
                v-for="count in [6, 8, 10, 12]"
                :key="count"
                class="setting-option"
                :class="{ active: gameSettings.maxBubbles === count }"
                @click="setMaxBubbles(count)"
              >
                {{ count }}个
              </view>
            </view>
          </view>

          <!-- 自动破碎时间 -->
          <view class="setting-group">
            <view class="setting-label">
              自动破碎时间
            </view>
            <view class="setting-options">
              <view
                v-for="time in [0, 3, 5, 7, 10]"
                :key="time"
                class="setting-option"
                :class="{ active: gameSettings.autoPopTime === time }"
                @click="setAutoPopTime(time)"
              >
                {{ time === 0 ? '关闭' : `${time}秒` }}
              </view>
            </view>
          </view>
        </view>

        <view class="settings-footer">
          <button class="settings-btn cancel-btn" @click="closeSettingsModal">
            取消
          </button>
          <button class="settings-btn confirm-btn" @click="applySettingsAndReset">
            确定重置
          </button>
        </view>
      </view>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.bubble-game-container {
  min-height: 100vh;
  background: linear-gradient(135deg, #6c5ce7 0%, #a29bfe 100%);
  padding: 20rpx;
  padding-bottom: env(safe-area-inset-bottom);
}

// 游戏信息栏
.game-header {
  display: flex;
  justify-content: space-between;
  background: rgba(255, 255, 255, 0.2);
  padding: 20rpx 30rpx;
  border-radius: 20rpx;
  margin-bottom: 20rpx;
  backdrop-filter: blur(10rpx);
}

.score-info,
.time-info {
  font-size: 32rpx;
  font-weight: 600;
  color: #fff;
  text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
}

// 游戏区域
.game-area {
  height: 1200rpx;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 24rpx;
  margin-bottom: 30rpx;
  position: relative;
  overflow: hidden;
  backdrop-filter: blur(10rpx);
}

// 游戏开始界面
.game-start {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #fff;
  text-align: center;
}

.start-icon {
  font-size: 120rpx;
  margin-bottom: 30rpx;
}

.start-title {
  font-size: 48rpx;
  font-weight: 700;
  margin-bottom: 20rpx;
  text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
}

.start-desc {
  font-size: 28rpx;
  opacity: 0.9;
  margin-bottom: 40rpx;
  line-height: 1.5;
}

.start-btn {
  background: linear-gradient(135deg, #ff6b6b 0%, #ff8e88 100%);
  color: #fff;
  border: none;
  padding: 20rpx 60rpx;
  border-radius: 50rpx;
  font-size: 32rpx;
  font-weight: 600;
  box-shadow: 0 8rpx 20rpx rgba(255, 107, 107, 0.4);
  transition: all 0.3s ease;

  &:active {
    transform: translateY(2rpx);
    box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.4);
  }
}

// 泡泡容器
.bubble-container {
  position: relative;
  height: 100%;
  width: 100%;

  // 启用多点触控
  touch-action: manipulation;
}

.bubble {
  position: absolute;
  border-radius: 50%;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2);
  cursor: pointer;
  opacity: 0.95;

  // 禁用长按选中效果
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;

  // 禁用长按弹出菜单
  -webkit-touch-callout: none;

  // 禁用高亮效果
  -webkit-tap-highlight-color: transparent;

  // 破碎样式1：经典放大消失
  &.burst1 {
    animation: bubbleBurst1 0.3s ease-out forwards;
  }

  // 破碎样式2：旋转缩放消失
  &.burst2 {
    animation: bubbleBurst2 0.4s ease-out forwards;
  }

  // 破碎样式3：震动后消失
  &.burst3 {
    animation: bubbleBurst3 0.5s ease-out forwards;
  }

  // 破碎样式4：向上飞出
  &.burst4 {
    animation: bubbleBurst4 0.4s ease-out forwards;
  }

  // 破碎样式5：脉冲消失
  &.burst5 {
    animation: bubbleBurst5 0.3s ease-out forwards;
  }
}

// 破碎动画1：经典放大消失
@keyframes bubbleBurst1 {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.4);
    opacity: 0.7;
  }
  100% {
    transform: scale(2);
    opacity: 0;
  }
}

// 破碎动画2：旋转缩放消失
@keyframes bubbleBurst2 {
  0% {
    transform: scale(1) rotate(0deg);
    opacity: 1;
  }
  30% {
    transform: scale(1.2) rotate(180deg);
    opacity: 0.8;
  }
  70% {
    transform: scale(0.3) rotate(360deg);
    opacity: 0.3;
  }
  100% {
    transform: scale(0) rotate(540deg);
    opacity: 0;
  }
}

// 破碎动画3：震动后消失
@keyframes bubbleBurst3 {
  0% {
    transform: scale(1) translateX(0);
    opacity: 1;
  }
  10% {
    transform: translateX(-5rpx);
  }
  20% {
    transform: translateX(5rpx);
  }
  30% {
    transform: translateX(-5rpx);
  }
  40% {
    transform: translateX(5rpx);
  }
  50% {
    transform: translateX(0) scale(1.3);
    opacity: 0.8;
  }
  100% {
    transform: scale(0);
    opacity: 0;
  }
}

// 破碎动画4：向上飞出
@keyframes bubbleBurst4 {
  0% {
    transform: scale(1) translateY(0);
    opacity: 1;
  }
  30% {
    transform: scale(0.8) translateY(-30rpx);
    opacity: 0.9;
  }
  70% {
    transform: scale(0.4) translateY(-60rpx);
    opacity: 0.5;
  }
  100% {
    transform: scale(0) translateY(-100rpx);
    opacity: 0;
  }
}

// 破碎动画5：脉冲消失
@keyframes bubbleBurst5 {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  20% {
    transform: scale(1.3);
    opacity: 0.9;
  }
  40% {
    transform: scale(0.9);
    opacity: 0.8;
  }
  60% {
    transform: scale(1.5);
    opacity: 0.5;
  }
  80% {
    transform: scale(0.5);
    opacity: 0.2;
  }
  100% {
    transform: scale(0);
    opacity: 0;
  }
}

// 游戏控制按钮
.game-controls {
  display: flex;
  gap: 20rpx;
  margin-bottom: 30rpx;
}

.control-btn {
  flex: 1;
  height: 80rpx;
  border: none;
  border-radius: 20rpx;
  font-size: 28rpx;
  font-weight: 500;
  transition: all 0.2s ease;

  &.restart-btn {
    background: linear-gradient(135deg, #00b894 0%, #00cec9 100%);
    color: #fff;
  }

  &.stop-btn {
    background: linear-gradient(135deg, #fdcb6e 0%, #f39c12 100%);
    color: #fff;
  }

  &.reset-btn {
    background: rgba(255, 255, 255, 0.2);
    color: #fff;
    backdrop-filter: blur(10rpx);
  }

  &:active {
    transform: scale(0.95);
  }
}

// 游戏说明
.game-instructions {
  background: rgba(255, 255, 255, 0.9);
  padding: 30rpx;
  border-radius: 20rpx;
  backdrop-filter: blur(10rpx);
}

.instruction-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #333;
  margin-bottom: 20rpx;
  text-align: center;
}

.instruction-list {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
}

.instruction-item {
  font-size: 26rpx;
  color: #666;
  line-height: 1.5;
}

// 设置对话框
.settings-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  backdrop-filter: blur(5rpx);
}

.settings-content {
  background: #fff;
  border-radius: 24rpx;
  width: 600rpx;
  max-height: 80vh;
  overflow: hidden;
  box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
}

.settings-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 30rpx;
  border-bottom: 1rpx solid #f0f0f0;
  background: linear-gradient(135deg, #6c5ce7 0%, #a29bfe 100%);
  color: #fff;
}

.settings-title {
  font-size: 36rpx;
  font-weight: 600;
}

.close-btn {
  font-size: 48rpx;
  font-weight: 300;
  width: 60rpx;
  height: 60rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);

  &:active {
    background: rgba(255, 255, 255, 0.3);
  }
}

.settings-body {
  padding: 30rpx;
  max-height: 60vh;
  overflow-y: auto;
}

.setting-group {
  margin-bottom: 40rpx;

  &:last-child {
    margin-bottom: 0;
  }
}

.setting-label {
  font-size: 28rpx;
  font-weight: 600;
  color: #333;
  margin-bottom: 20rpx;
}

.setting-options {
  display: flex;
  flex-wrap: wrap;
  gap: 16rpx;
}

.setting-option {
  padding: 16rpx 24rpx;
  background: #f8f9fa;
  border: 2rpx solid transparent;
  border-radius: 16rpx;
  font-size: 26rpx;
  color: #666;
  transition: all 0.2s ease;

  &.active {
    background: linear-gradient(135deg, #6c5ce7 0%, #a29bfe 100%);
    color: #fff;
    border-color: #6c5ce7;
    transform: scale(1.05);
  }

  &:active {
    transform: scale(0.95);
  }
}

.settings-footer {
  display: flex;
  gap: 20rpx;
  padding: 30rpx;
  border-top: 1rpx solid #f0f0f0;
  background: #fafbfc;
}

.settings-btn {
  flex: 1;
  height: 80rpx;
  border: none;
  border-radius: 16rpx;
  font-size: 28rpx;
  font-weight: 500;
  transition: all 0.2s ease;

  &.cancel-btn {
    background: #f8f9fa;
    color: #666;
    border: 2rpx solid #e9ecef;
  }

  &.confirm-btn {
    background: linear-gradient(135deg, #6c5ce7 0%, #a29bfe 100%);
    color: #fff;
    box-shadow: 0 4rpx 12rpx rgba(108, 92, 231, 0.3);
  }

  &:active {
    transform: scale(0.95);
  }
}

// 祝福文字特效
.blessing-text {
  position: absolute;
  font-size: 32rpx;
  font-weight: 700;
  pointer-events: none;
  z-index: 100;
  text-shadow:
    0 0 8rpx rgba(255, 255, 255, 0.8),
    0 0 16rpx rgba(255, 255, 255, 0.6),
    2rpx 2rpx 4rpx rgba(0, 0, 0, 0.3);
  animation: blessingFloat 1.5s ease-out forwards;
  transform-origin: center;

  // 添加发光效果
  filter: drop-shadow(0 0 6rpx currentColor);

  // 字体样式
  letter-spacing: 2rpx;
  white-space: nowrap;
}

// 祝福文字浮现动画
@keyframes blessingFloat {
  0% {
    transform: translate(-50%, -50%) scale(0.5);
    opacity: 0;
  }
  20% {
    transform: translate(-50%, -50%) scale(1.2);
    opacity: 1;
  }
  40% {
    transform: translate(-50%, -60%) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -120%) scale(0.8);
    opacity: 0;
  }
}
</style>
